home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #2 / Amiga Plus CD - 1995 - No. 2.iso / startrek / trek73 / src / subs.c < prev   
C/C++ Source or Header  |  1995-04-11  |  8KB  |  415 lines

  1. /*
  2.  * TREK73: subs.c
  3.  *
  4.  * Miscellaneous Subroutines
  5.  *
  6.  * ship_name, newitem, delitem, rangefind, bearing, phaser_hit,
  7.  * torpedo_hit, damage, antimatter_hit, recitfy
  8.  */
  9.  
  10. #include "defines.h"
  11. #include "structs.h"
  12. #include <math.h>
  13. #include <ctype.h>
  14.  
  15. extern struct ship *shiplist[];
  16. extern char science[];
  17.  
  18. struct ship *ship_name(name, start)
  19. char *name;
  20. int start;
  21. {
  22.     extern    int shipnum;
  23.     register int i;
  24.     register int j;
  25.     register int len;
  26.  
  27.     if (islower(*name)) {
  28.         *name = toupper(*name);
  29.     }
  30.     j = shipnum;
  31.     len = strlen(name);
  32.     for (i=start; i<=j; i++) {
  33.         if (shiplist[i]->name[0] == NULL)
  34.             continue;
  35.         if (strncmp(name, shiplist[i]->name, len) == 0)
  36.             return shiplist[i];
  37.     }
  38.     printf("%s: I am unable to find the %s\n", science, name);
  39.     return NULL;
  40. }
  41.  
  42.  
  43. struct list *newitem(item)
  44. int item;
  45. {
  46.     extern    struct list head;
  47.     extern    struct list *tail;
  48.     register struct    list *new;
  49.     register struct    list *newtail;
  50.  
  51.     /*
  52.      * if there's no "tail" node, make one (only happens at init)
  53.      */
  54.     if (tail == NULL) {
  55.         new = MKNODE(struct list, *, 1);
  56.         new->back = &head;
  57.         new->fwd = NULL;
  58.         new->data.tp = NULL;
  59.         head.fwd = new;
  60.         tail = new;
  61.     }
  62.     new = tail;
  63.     /*
  64.      * now make the new tail node
  65.      */
  66.     newtail = MKNODE(struct list, *, 1);
  67.     newtail->back = new;
  68.     newtail->fwd = NULL;
  69.     newtail->data.tp = NULL;
  70.     newtail->type = 0;
  71.     tail = newtail;
  72.     /*
  73.      * link the old tail node to the new one
  74.      */
  75.     new->type = item;
  76.     new->fwd = newtail;
  77.     return new;
  78. }
  79.  
  80.  
  81. int delitem(item)
  82. struct list *item;
  83. {
  84.     extern    struct list *tail;
  85.     extern    struct list head;
  86.     register struct list *bp;
  87.     register struct list *fp;
  88.  
  89.     bp = item->back;
  90.     fp = item->fwd;
  91.     if (item->data.tp != NULL)
  92.         free((char *) item->data.tp);
  93.     /*
  94.      * re-arrange pointers on both the next and the previous
  95.      * nodes; if no forward pointer, we were the tail so make
  96.      * the bp the new tail node.
  97.      */
  98.     if (fp != NULL) {
  99.         bp->fwd = fp;
  100.         fp->back = bp;
  101.     } else {
  102.         tail = bp;
  103.         bp->fwd = NULL;
  104.     }
  105.     free((char *) item);
  106. }
  107.  
  108. int rangefind(x1, x2, y1, y2)
  109. int x1;
  110. int x2;
  111. int y1;
  112. int y2;
  113. {
  114.     extern    double sqrt();
  115.     extern    double atan();
  116.     register int i;
  117.     register int x, y;
  118.     double    d1, d2;
  119.  
  120.     x = x2 - x1;
  121.     y = y2 - y1;
  122.     /*
  123.      * Both x and y must be cast as double else overflow
  124.      * may occur.
  125.      */
  126.     d1 = (double) x * (double) x + (double) y * (double) y;
  127.     d2 = sqrt(d1);
  128.     i = d2;
  129.     return i;
  130. }
  131.  
  132. /*
  133.  * This routine finds the bearing of (x2,y2) from (x1,y1)
  134.  */
  135. int bearing(x1, x2, y1, y2)
  136. int x1;
  137. int x2;
  138. int y1;
  139. int y2;
  140. {
  141.     extern double atan();
  142.     float    x;
  143.     float    y;
  144.     register int bear;
  145.     double    d1;
  146.     double    d2;
  147.  
  148.     x = x2 - x1;
  149.     y = y2 - y1;
  150.     if (x == 0.0)
  151.         bear = 90;
  152.     else {
  153.         d1 = y/x;
  154.         d2 = atan(d1) * 57.2958;
  155.         bear = d2;
  156.     }
  157.     if (x < 0.0 || y < 0.0) {
  158.         bear += 180;
  159.         if (x >= 0.0)
  160.             bear += 180;
  161.     }
  162.     return bear;
  163. }
  164.  
  165. int phaser_hit(sp, x, y, bank, true_bear)
  166. struct ship *sp;
  167. int x;
  168. int y;
  169. struct phaser *bank;
  170. int true_bear;
  171. {
  172.     extern    double sqrt();
  173.     register int hit;
  174.     int    i;
  175.     int    spread;
  176.     int    bear;
  177.     double    d1;
  178.     double    d2;
  179.  
  180.     hit = 0;
  181.     i = rangefind(sp->x, x, sp->y, y);
  182.     if (i < 1000) {
  183.         bear = bearing(sp->x, x, sp->y, y);
  184.         spread = rectify(true_bear - bear);
  185.         /*
  186.          * Check if a target is within the phaser spread
  187.          */
  188.         if (spread > sp->p_spread && 360-spread > sp->p_spread)
  189.             return 0;
  190.         d1 = 1.0 - (float)i/1000.0;
  191.         d2 = (float)bank->load * sqrt(d1) * sp->p_percent / 100;
  192.         d2 = (float)bank->load * d2 * 45.0/(float)sp->p_spread * sp->p_percent / 100;
  193.         hit = d2/10.0;
  194.     }
  195.     return hit;
  196. }
  197.  
  198. int torpedo_hit(fuel, x, y, tx, ty)
  199. int fuel;
  200. int x;
  201. int y;
  202. int tx;
  203. int ty;
  204. {
  205.     extern    double sqrt();
  206.     register int hit;
  207.     int    i;
  208.     double    d1;
  209.     double    d2;
  210.     float    f1;
  211.     float    f2;
  212.  
  213.     hit = 0;
  214.     i = rangefind(x, tx, y, ty);
  215.     f1 = fuel * 5.0;
  216.     f2 = f1 * 10.0;
  217.     if (i < f2) {
  218.         d1 = 1.0 - (float)i/f2;
  219.         d2 = (float)f1 * sqrt(d1);
  220.         hit = d2;
  221.     }
  222.     return hit;
  223. }
  224.  
  225.  
  226. damage(hit, ep, s, dam)
  227. int hit;
  228. struct ship *ep;
  229. int s;
  230. struct damage *dam;
  231. {
  232.     register int i;
  233.     register int j;
  234.     register int k;
  235.     float    f1;
  236.     float    f2;
  237.     struct ship *fed;
  238.  
  239.     fed = shiplist[0];
  240.     printf("hit %d on %s's shield %d\n", hit, ep->name, s);
  241.     s--;
  242.     /*
  243.      * Note that if the shield is at 100% efficiency, no
  244.      * damage at all will be taken
  245.      */
  246.     f1 = hit * (1.0 - ep->shields[s].eff * ep->shields[s].drain);
  247.     if (f1 < 0)
  248.         return 0;
  249.     ep->eff += f1/dam->eff;
  250.     ep->pods -= f1/dam->fuel;
  251.     ep->energy -= f1/dam->fuel;
  252.     ep->regen -= f1/dam->regen;
  253.     if (ep->regen < 0.0)
  254.         ep->regen = 0.0;
  255.     if (ep->pods < 0.0)
  256.         ep->pods = 0.0;
  257.     if (ep->energy < 0.0)
  258.         ep->energy = 0.0;
  259.     if (ep->pods < ep->energy)
  260.         ep->energy = ep->pods;
  261.     f2 = dam->shield * 100;
  262.     if (s == 0)
  263.         f2 *= 1.5;
  264.     ep->shields[s].eff -= max(hit/f2, 0);
  265.     if (ep->shields[s].eff < 0.0)
  266.         ep->shields[s].eff = 0.0;
  267.     j = f1 * dam->crew;
  268.     if (j > 0)
  269.         ep->crew -= max(randm(j), 0);
  270.     if (ep->crew < 0)
  271.         ep->crew = 0;
  272.     j = f1/dam->weapon;
  273.     for(i=0; i<j; i++) {
  274.         k = randm(10);
  275.         if (k <= 4) {
  276.             k--;
  277.             if (ep->phasers[k].status & P_DAMAGED)
  278.                 continue;
  279.             ep->phasers[k].status |= P_DAMAGED;
  280.             /*
  281.              * Reroute the energy
  282.              * back to the engines
  283.              */
  284.             ep->energy = min(ep->pods,
  285.                 ep->energy + ep->phasers[k].load);
  286.             ep->phasers[k].load = 0;
  287.             ep->phasers[k].drain = 0;
  288.             k++;
  289.             if (ep == fed)
  290.                 printf("   phaser %d damaged.\n", k);
  291.         } else {
  292.             k -= 5;
  293.             if (ep->tubes[k].status & T_DAMAGED)
  294.                 continue;
  295.             /*
  296.              * If tubes are damaged, reroute the pods
  297.              * back to the engines
  298.              */
  299.             ep->pods += ep->tubes[k].load;
  300.             ep->energy += ep->tubes[k].load;
  301.             ep->tubes[k].load = 0;
  302.             ep->tubes[k].status |= T_DAMAGED;
  303.             k++;
  304.             if (ep == fed)
  305.                 printf("   tube %d damaged\n", k);
  306.         }
  307.     }
  308.     for (i=0; i<4; i++) {
  309.         if (ep->status & 1<<i)
  310.             continue;
  311.         if (randm(dam->stats[i].roll) < f1) {
  312.             ep->status |= 1<<i;
  313.             if (ep == fed)
  314.                 printf("   %s\n", dam->stats[i].mesg);
  315.         }
  316.     }
  317. #ifdef HISTORICAL
  318.     /*
  319.      * Historically, if more than 43 points of damage were done
  320.      * to the ship, it would destroy itself.  This led to much
  321.      * abuse of probes and thus has been enclosed inside of
  322.      * an #ifdef
  323.      */
  324.     if (f1 > 43)
  325.         ep->delay = 1;
  326. #endif
  327.     return 0;
  328. }
  329.  
  330.  
  331. antimatter_hit(ptr, x, y, fuel)
  332. char *ptr;
  333. int x;
  334. int y;
  335. int fuel;
  336. {
  337.     extern    struct list head;
  338.     extern    struct list *tail;
  339.     extern    struct damage a_damage;
  340.     register struct list *lp;
  341.     register int hit;
  342.     int    tarx, tary;
  343.     int    s;
  344.     int    bear;
  345.     struct     torpedo *tp;
  346.     struct    ship *sp;
  347.  
  348.     for (lp = &head; lp != tail; lp = lp->fwd) {
  349.         if (lp->type == 0)
  350.             continue;
  351.         sp = NULL;
  352.         tp = NULL;
  353.         if (lp->type == I_SHIP) {
  354.             sp = lp->data.sp;
  355.             tarx = sp->x;
  356.             tary = sp->y;
  357.         } else {
  358.             tp = lp->data.tp;
  359.             tarx = tp->x;
  360.             tary = tp->y;
  361.         }
  362.         if (sp == (struct ship *) ptr || tp == (struct torpedo *) ptr)
  363.             continue;
  364.         hit = torpedo_hit(fuel, x, y, tarx, tary);
  365.         if (hit <= 0)
  366.             continue;
  367.         if (sp) {
  368.             /* 
  369.              * Determine which shield is hit
  370.              */
  371.             bear = rectify(bearing(tarx, x, tary, y) - sp->course);
  372.             if (bear < 45 || bear > 315)
  373.                 s = 1;
  374.             else if (bear < 135)
  375.                 s = 2;
  376.             else if (bear < 225)
  377.                 s = 3;
  378.             else
  379.                 s = 4;
  380.             damage(hit, sp, s, &a_damage);
  381.         } else {
  382.             if (tp->timedelay <= 2)
  383.                 continue;
  384.             tp->timedelay = 2;
  385.             switch (lp->type) {
  386.                 case I_TORPEDO:
  387.                     printf("hit on torpedo %d\n", 
  388.                         tp->id);
  389.                     break;
  390.                 case I_PROBE:
  391.                     printf("hit on probe %d\n", 
  392.                         tp->id);
  393.                     break;
  394.                 case I_ENG:
  395.                     printf("hit on %s engineering\n",
  396.                         tp->from->name);
  397.                     break;
  398.             }
  399.         }
  400.     }
  401. }
  402.  
  403. int rectify(x)
  404. int x;
  405. {
  406.     register int ret;
  407.  
  408.     ret = x;
  409.     if (ret < 0)
  410.         ret += 360;
  411.     else if (ret > 360)
  412.         ret -= 360;
  413.     return ret;
  414. }
  415.